Program coloring_program;
Program color_matrix_program;
Program linear_gradient_program;
+ Program blur_program;
};
};
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient_program, start_point_location, "uStartPoint");
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient_program, end_point_location, "uEndPoint");
+ self->blur_program.id = gsk_shader_builder_create_program (builder,
+ "blur.vs.glsl", "blur.fs.glsl",
+ &shader_error);
+ if (shader_error != NULL)
+ {
+ g_propagate_prefixed_error (error,
+ shader_error,
+ "Unable to create 'blur' program: ");
+ goto out;
+ }
+ self->blur_program.index = 6;
+ self->blur_program.name = "blur";
+ init_common_locations (self, builder, &self->blur_program);
+ INIT_PROGRAM_UNIFORM_LOCATION (blur_program, blur_radius_location, "uBlurRadius");
+ INIT_PROGRAM_UNIFORM_LOCATION (blur_program, blur_size_location, "uSize");
+
res = TRUE;
out:
}
break;
+ case GSK_BLUR_NODE:
+ {
+ int texture_id;
+ gboolean is_offscreen;
+ RenderOp op;
+ add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y,
+ gsk_blur_node_get_child (node),
+ &texture_id, &is_offscreen);
+
+ ops_set_program (builder, &self->blur_program);
+ op.op = OP_CHANGE_BLUR;
+ graphene_size_init_from_size (&op.blur.size, &node->bounds.size);
+ op.blur.radius = gsk_blur_node_get_radius (node);
+ ops_add (builder, &op);
+
+ ops_set_texture (builder, texture_id);
+
+ if (is_offscreen)
+ {
+ GskQuadVertex vertex_data[GL_N_VERTICES] = {
+ { { min_x, min_y }, { 0, 1 }, },
+ { { min_x, max_y }, { 0, 0 }, },
+ { { max_x, min_y }, { 1, 1 }, },
+
+ { { max_x, max_y }, { 1, 0 }, },
+ { { min_x, max_y }, { 0, 0 }, },
+ { { max_x, min_y }, { 1, 1 }, },
+ };
+
+ ops_draw (builder, vertex_data);
+ }
+ else
+ {
+ ops_draw (builder, vertex_data);
+ }
+ }
+ break;
+
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_BORDER_NODE:
case GSK_INSET_SHADOW_NODE:
case GSK_OUTSET_SHADOW_NODE:
- case GSK_BLUR_NODE:
case GSK_SHADOW_NODE:
case GSK_CROSS_FADE_NODE:
case GSK_BLEND_NODE:
op->linear_gradient.end_point.x, op->linear_gradient.end_point.y);
break;
+ case OP_CHANGE_BLUR:
+ g_assert (program == &self->blur_program);
+ glUniform1f (program->blur_radius_location, op->blur.radius);
+ glUniform2f (program->blur_size_location, op->blur.size.width, op->blur.size.height);
+ break;
+
case OP_DRAW:
OP_PRINT (" -> draw %ld, size %ld and program %s\n",
op->draw.vao_offset, op->draw.vao_size, program->name);
--- /dev/null
+
+uniform float uBlurRadius = 4.0;
+uniform vec2 uSize;
+
+const int samples_x = 15; // must be odd
+const int samples_y = 15; // must be odd
+
+const int half_samples_x = samples_x / 2;
+const int half_samples_y = samples_y / 2;
+
+float Gaussian (float sigma, float x)
+{
+ return exp ( - (x * x) / (2.0 * sigma * sigma));
+}
+
+vec4 blur_pixel (in vec2 uv)
+{
+ float total = 0.0;
+ vec4 ret = vec4 (0);
+ float pixel_size_x = (1.0 / uSize.x);
+ float pixel_size_y = (1.0 / uSize.y);
+
+ for (int y = 0; y < samples_y; ++y)
+ {
+ float fy = Gaussian (uBlurRadius, float(y) - float(half_samples_x));
+ float offset_y = float(y - half_samples_y) * pixel_size_y;
+ for (int x = 0; x < samples_x; ++x)
+ {
+ float fx = Gaussian (uBlurRadius, float(x) - float(half_samples_x));
+ float offset_x = float(x - half_samples_x) * pixel_size_x;
+ total += fx * fy;
+ ret += Texture(uSource, uv + vec2(offset_x, offset_y)) * fx * fy;
+ }
+ }
+ return ret / total;
+}
+
+void main()
+{
+ /*color = clip (inPos, blur_pixel (inTexCoord));*/
+ setOutputColor(blur_pixel(vUv));
+}